<?php

namespace App\Command\ResumeParsing\Service\ParsingSpecial;

use EchoPHP\Facades\Log as Log;
use PhpOffice\PhpSpreadsheet;

class Parsing51jobExcel extends ParsingSpecialExcel implements PreprocessorExcel {

    protected $titlePatternTemplate = ['range' => 'B3:C3', 'core' => 'B3', 'xfIndex' => null];

    private $indexPageTitleRow = [[
        '姓名', '匹配度', '简历编号', '应聘职位', '应聘公司', '发布城市', '应聘日期', '性别', '出生日期', '目前居住地', '户口/国籍', '工作年限',
        '学历/学位', '毕业学校', '专业', '联系电话', '电子邮件', '地址', '邮编', '最近一家公司', '最近一个职位', '目前年收入', '期望薪资', '求职状态'
    ]];

    public function __construct($helper) {
        parent::__construct($helper);

        $this->get['id'] = function () {
            return $this->data['misc']['简历编号'] ?? '';
        };

        $this->get['time'] = function () {
            return $this->data['misc']['更新时间'] ?? '';
        };

        $this->get['name'] = function () {
            return $this->data['个人信息']['姓名'] ?? '';
        };

        $this->get['sex'] = function () {
            return $this->data['个人信息']['性别'] ?? '';
        };

        $this->get['nation'] = $this->tagNotExist;

        $this->get['identitycard'] = $this->tagNotExist;

        $this->get['mobile'] = function () {
            return $this->data['个人信息']['手机'] ?? '';
        };

        $this->get['email'] = function () {
            return $this->data['个人信息']['邮箱'] ?? '';
        };

        $this->get['age'] = $this->tagNotExist;

        $this->get['married'] = function () {
            return $this->data['个人信息']['婚姻状态'] ?? '';
        };

        $this->get['politic'] = function () {
            return $this->data['个人信息']['政治面貌'] ?? '';
        };

        $this->get['degree'] = $this->tagNotExist;

        $this->get['industry'] = function () {
            return $this->data['求职意向']['行业'] ?? '';
        };

        $this->get['position'] = function () {
            return $this->formatTxt($this->data['求职意向']['职能/职位'] ?? '', 'space');
        };

        $this->get['career'] = $this->tagNotExist;

        $this->get['major'] = $this->tagNotExist;

        $this->get['birthday'] = function () {
            return $this->data['个人信息']['出生日期'] ?? '';
        };

        $this->get['workyear'] = function () {
            return $this->data['个人信息']['工作年限'] ?? '';
        };

        $this->get['workarea'] = function () {
            return $this->data['个人信息']['居住地'] ?? '';
        };

        $this->get['expectarea'] = function () {
            return $this->data['求职意向']['地点'] ?? '';
        };

        $this->get['area'] = function () {
            return $this->data['个人信息']['户口/国籍'] ?? '';
        };

        $this->get['salary'] = function () {
            $resultText = $this->data['目前年收入']['目前年收入'] ?? '';
            $salary = $this->func->parseSalary($resultText, 'annual');
            if (count($salary)) {
                $this->helper->resumeInfo['salaryfrom'] = $salary['monthly']['begin'];
                $this->helper->resumeInfo['salaryend'] = $salary['monthly']['end'];
            }
            return $resultText;
        };

        $this->get['expectsalary'] = function () {
            $resultText = $this->data['求职意向']['期望薪资'] ?? '';
            $expectSalary = $this->func->parseSalary($resultText);
            if (count($expectSalary)) {
                $this->helper->resumeInfo['expectsalaryfrom'] = $expectSalary['monthly']['begin'];
                $this->helper->resumeInfo['expectsalaryend'] = $expectSalary['monthly']['end'];
            }
            return $resultText;
        };

        $this->get['jobterm'] = function () {
            return $this->data['求职意向']['工作类型'] ?? '';
        };

        $this->get['entrytime'] = function () {
            return $this->data['求职意向']['到岗时间'] ?? '';
        };

        $this->get['current_situation'] = function () {
            return $this->data['个人信息']['求职状态'] ?? '';
        };

        $this->get['school'] = $this->tagNotExist;

        $this->get['nofocuse'] = $this->tagNotExist;

        $this->groupGetter['work'] = [];

        $this->groupGetter['work'][0] = function ($group) {
            return preg_split('/\s*[\r\n]\s*/u', $group);
        };

        $this->groupGetter['work'][] = function ($row) {
            if (preg_match('/^(?<time>(?<!\d)(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:\s*[-–—\/\\\\~到至]\s*(?:至?今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))(?!\d))?)\s*(?:——\s*公司:\s*)?(?<company>.+?)?(?:\((?<scale>\S*\d+\S*人\S*)\))?$/u', $row, $matches)) {
                $time = $matches['time'];
                $tmp = $this->func->parseTimespan($time);
                return ['comment' => !empty($matches['scale']) ? '公司规模：' . $matches['scale'] : '', 'time' => $time, 'time_from' => $tmp['begin'], 'time_end' => $tmp['end'], 'company' => $matches['company']];
            }
        };

        $this->groupGetter['work'][] = function ($row) {
            if (preg_match('/^行业\s*:\s*(?<industry>.+)$/u', $row, $matches)) {
                return ['industry' => $matches['industry']];
            }
        };

        $this->groupGetter['work'][] = function ($row) {
            if (preg_match('/^职位\s*:\s*(?<duty>.+)$/u', $row, $matches)) {
                return ['duty' => $matches['duty']];
            }
        };

        $this->get['workinfo'] = function () {
            $workInfo = array_column($this->data['工作经验'] ?? [], 1);
            $data = [];
            foreach ($workInfo as $group) {
                if (empty($group)) continue;
                $tmp = $this->groupProcess('work', $group);
                $tmp['comment'] = preg_replace('/\s*[:：]\s*/u', '：', $tmp['comment']);
                $data[] = $tmp;
            }
            return $data;
        };

        $this->groupGetter['project'] = [];

        $this->groupGetter['project'][0] = function ($group) {
            return preg_split('/\s*[\r\n]\s*/u', $group);
        };

        $this->groupGetter['project'][] = function ($row) {
            if (preg_match('/^(?<time>(?<!\d)(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:\s*[-–—\/\\\\~到至]\s*(?:至?今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))(?!\d))?)\s*(?:——\s*)?(?<project>.+?)?$/u', $row, $matches)) {
                $time = $matches['time'];
                $tmp = $this->func->parseTimespan($time);
                return ['time' => $time, 'time_from' => $tmp['begin'], 'time_end' => $tmp['end'], 'project' => $matches['project']];
            }
        };

        $this->groupGetter['project'][] = function ($row) {
            if (preg_match('/^所属公司\s*：\s*(?<company>.+)$/u', $row, $matches)) {
                return ['company' => $matches['company']];
            }
        };

        $this->get['projectinfo'] = function () {
            $projectInfo = array_column($this->data['项目经验'] ?? [], 1);
            $data = [];
            foreach ($projectInfo as $group) {
                if (empty($group)) continue;
                $data[] = $this->groupProcess('project', $group);
            }
            return $data;
        };

        $this->get['educationinfo'] = function () {
            $educationInfo = array_column($this->data['教育经历'] ?? [], 1);
            $data = [];
            foreach ($educationInfo as $row) {
                if (preg_match('/^(?<time>(?<!\d)(?:(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?|(?:19|20)?\d{2}\s*(?<delimiter>[\-\.\/\\\\])\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?)(?!\d)(?:\s*[-–—\/\\\\~到至]\s*(?:至?今|现在|(?(delimiter)(?:19|20)?\d{2}\s*\k<delimiter>\s*[01]?\d(?:\k<delimiter>\s*[0-3]?\d)?|(?:19|20)?\d{2}\s*年\s*[01]?\d\s*月(?:\s*[0-3]?\d[日号])?))(?!\d))?)\s*(?:——\s*)?(?<school>[^\r\n]+)\s*[\r\n]\s*(?:(?<major>\S+)[^\S\r\n]+)?(?<degree>\S+)(?:\s*[\r\n]\s*(?<comment>.+))?$/us', $row, $matches)) {
                    $time = $matches['time'];
                    $tmp = $this->func->parseTimespan($time);
                    $data[] = ['comment' => $matches['comment'] ?? '',
                        'time' => $time,
                        'time_from' => $tmp['begin'],
                        'time_end' => $tmp['end'],
                        'school' => $matches['school'],
                        'major' => $matches['major'] ?? '',
                        'degree' => $matches['degree']
                    ];
                }
            }
            return $data;
        };

        $this->get['skillinfo'] = function () {
            return $this->data['技能特长']['技能/语言'] ?? '';
        };

        $this->get['awardinfo'] = function () {
            return $this->data['在校情况']['校内荣誉'] ?? '';
        };

        $this->get['commentinfo'] = function () {
            return $this->data['求职意向']['自我评价'] ?? '';
        };

        $this->get['otherinfo'] = function () {
            $resultText = '';
            $map = [
                '培训经历' => $this->data['技能特长']['培训经历'] ?? '',
                '证书' => $this->data['技能特长']['证书'] ?? '',
                '校内职务' => $this->data['在校情况']['校内职务'] ?? '',
                '求职信' => $this->data['求职信']['求职信'] ?? '',
                '其他' => $this->data['附加信息']['其他'] ?? ''
            ];
            foreach ($map as $key => $value) {
                if (!empty($value)) $resultText .= "\r\n" . $key . "\r\n" . $value;
            }
            return trim($resultText);
        };
    }

    protected function matchTitleStyle() {
        $rowEnd = $this->titlePattern['core'][1] + 20;
        for ($row = $this->titlePattern['core'][1]; $row < $rowEnd && ($cell = $this->sheet->getCellByColumnAndRow($this->titlePattern['core'][0], $row, false)); $row++) {
            if ($cell->getValue() == '个人信息') {
                $style = $cell->getStyle();
                break;
            }
        }
        if (empty($style)) return false;
        if ($style->getFill()->getStartColor()->getARGB() != 'FF99CCFF') return false;
        if ($style->getFill()->getFillType() != PhpSpreadsheet\Style\Fill::FILL_SOLID) return false;
        if ($style->getFont()->getSize() != 9) return false;
        if ($style->getFont()->getName() != '宋体') return false;
        if ($style->getBorders()->getLeft()->getColor()->getARGB() != 'FF99CCFF') return false;
        if ($style->getBorders()->getLeft()->getBorderStyle() != PhpSpreadsheet\Style\Border::BORDER_MEDIUM) return false;
        return $cell->getXfIndex();
    }

    protected function test() {
        if (!$this->getTitlePattern()) return false;
        if ($this->sheet->getCellByColumnAndRow(2, 1)->getValue() != '个人简历') return false;
        return true;
    }

    protected function onParsed() {
        $this->explode();
        foreach (['misc', '个人信息', '目前年收入', '求职意向', '在校情况', '技能特长', '附加信息', '求职信'] as $title) {
            $this->data[$title] = $this->pairRowData($this->data[$title]);
        }
    }

    /**
     * Excel文档预处理方法，在此方法中，直接对$workbook对象进行必要的修改。
     * @param PhpSpreadsheet\Spreadsheet $workbook 待处理的Excel文档对象
     * @return bool 若Excel格式不匹配当前指定渠道，则返回false；否则返回true。
     */
    public function preprocess(PhpSpreadsheet\Spreadsheet $workbook) {
        try {
            $indexSheet = $workbook->getSheet(0);
            if ($indexSheet->rangeToArray('A1:X1') != $this->indexPageTitleRow) return false;

            $styleChecked = false;
            for ($row = 2; $row <= $indexSheet->getHighestRow(); $row++) {
                if (empty($nameCell = $indexSheet->getCellByColumnAndRow(1, $row, false))) continue;
                if (empty($targetSheet = $this->getLinkTargetSheet($nameCell))) continue;
                if (!$styleChecked) {
                    if (!$this->canParse($targetSheet)) return false;
                    $styleChecked = true;
                }
                try {
                    if ($idCell = $indexSheet->getCellByColumnAndRow(3, $row, false)) {
                        for ($insertRow = 4; !empty($cell = $targetSheet->getCellByColumnAndRow(2, $insertRow, false)) && $insertRow < 20; $insertRow++) {
                            if (empty($cell->getValue())) break;
                            if ($this->getTitle($insertRow)) break;
                        }
                        $targetSheet->insertNewRowBefore($insertRow);
                        $targetSheet->getCellByColumnAndRow(2, $insertRow)->setValue('简历编号');
                        $targetSheet->getCellByColumnAndRow(3, $insertRow)->setValue($idCell->getValue());
                    }
                } catch (\Exception $e) {
                    Log::error(e_dump($e), ['row' => $row], 'cmd');
                }
            }
            foreach ($workbook->getWorksheetIterator() as $sheet) { //自动设置多行单元格的高度
                $sheet->getDefaultRowDimension()->setRowHeight(-1);
                foreach ($sheet->getRowDimensions() as $rowDimension) {
                    $rowDimension->setRowHeight(-1);
                }
            }
            $workbook->removeSheetByIndex(0);
            return true;
        } catch (\Exception $e) {
            Log::error(e_dump($e), [], 'cmd');
            return false;
        }
    }
}
